#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <pthread.h> // 原生线程库的头文件

const int threadnum = 5;

class Task
{
public:
    Task()
    {}
    void SetData(int x, int y)
    {
        datax = x;
        datay = y;
    }
    int Excute()
    {
        return datax + datay;
    }
    ~Task()
    {

    }
private:
    int datax;
    int datay;
};

class ThreadData : public Task
{
public:
    ThreadData(int x, int y, const std::string &threadname):_threadname(threadname)
    {
        _t.SetData(x, y);
    }
    std::string threadname()
    {
        return _threadname;
    }
    int run()
    {
        return _t.Excute();
    }
private:
    std::string _threadname;
    Task _t;
};

class Result
{
public:
    Result(){}
    ~Result(){}
    void SetResult(int result, const std::string &threadname)
    {
        _result = result;
        _threadname = threadname;
    }
    void Print()
    {
        std::cout << _threadname << " : " << _result << std::endl;
    }
private:
    int _result;
    std::string _threadname;
};


void *handlerTask(void *args)
{
    ThreadData *td = static_cast<ThreadData*>(args);
    std::string name = td->threadname();

    Result* res = new Result();
    int result = td->run();
    res->SetResult(result, name);
    std:: cout << name << "run result : " << result << std::endl;
    delete td;
    sleep(2);

    return res;
}

//1 多线程创建
//2 线程传参和返回值，我们可以传递级别信息，也可以传递其他对象(包括你自己定义的！)
int main()
{
    std::vector<pthread_t> threads;
    for (int i = 0; i < threadnum; i++)
    {
        char threadname[64];
        snprintf(threadname, 64, "Thread-%d", i + 1);
        ThreadData* td = new ThreadData(10, 20, threadname);

        pthread_t tid;
        pthread_create(&tid, nullptr, handlerTask, td);
        threads.push_back(tid);
    }

    void *ret = nullptr;
    std::vector<Result*> result_set;

    for (auto &tid : threads)
    {
        pthread_join(tid, &ret);
        result_set.push_back((Result*)ret);
    }

    for(auto& res : result_set)
    {
        res->Print();
        delete  res;
    }

    return 0;
}


















// void *handlerTask(void *args)
// {
//     ThreadData *td = static_cast<ThreadData *>(args);

//     std::string name = td->threadname();

//     Result *res = new Result();
//     int result = td->run();

//     res->SetResult(result, name);

//     // std::cout << name << "run result : " << result << std::endl;
//     delete td;

//     sleep(2);
//     return res;
//     // // std::string threadname =static_cast<char*>(args);
//     // const char *threadname = static_cast<char *>(args);
//     // while (true)
//     // {
//     //     std::cout << "I am " << threadname << std::endl;
//     //     sleep(2);
//     // }

//     // delete []threadname;

//     // return nullptr;
// }






// std::string ToHex(pthread_t tid)
// {
//     char id[64];
//     snprintf(id, sizeof(id), "0x%lx", tid);
//     return id;
// }

// int g_val = 100;

// void *threadrun(void *args)
// {
//     std::string threadname = (char*)args;
//     int cnt = 5;
//     while(cnt)
//     {
//         sleep(1);        
//         std::cout << threadname<< " is running: " << std::endl;
//         cnt--;
//     }

//     //pthread_exit((void*)123);
//     return (void*)123; // warning
//     // exit(10); // 不能用exit终止线程，因为它是终止进程的.
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadrun, (void*)"thread-1");

//     sleep(2);
//     pthread_cancel(tid);//新线程跑2秒, 就被取消

//     void* ret = nullptr;

//     int cnt = 10;
//     while(cnt)
//     {
//         std::cout << "main thread is running: " << std::endl;
//         sleep(1);
//         cnt--;
//     }

//     pthread_join(tid, &ret);
//     std::cout << "  ret: " << (long long)ret << std::endl;
//     return 0;
// }









// void *threadrun(void *args)
// {
//     std::string threadname = (char*)args;
//     int cnt = 5;
//     while(cnt)
//     {
//         std::cout << threadname<< " is running: " 
//         << cnt  << "  pid-->" << getpid() 
//         << "  mythread is -->" <<ToHex(pthread_self()) 
//         <<"  g_val: " << g_val << "  &gval "<< &g_val << std::endl;

//         g_val++;
//         sleep(1);
//         cnt--;
//     }

//     //return nullptr;
//     return (void*)123; // warning
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadrun, (void*)"thread-1");

//     void* ret = nullptr;

//     int cnt = 10;
//     while(cnt)
//     {
//         std::cout << "main thread is running: " << cnt 
//         << "  pid-->" << getpid() 
//         << "  new thread ID--> "<< ToHex(tid)
//         << "  main thread is -->" <<ToHex(pthread_self()) 
//         <<"  g_val: " << g_val << "  &gval "<< &g_val << std::endl;
//         sleep(1);
//         cnt--;
//     }

//     int n = pthread_join(tid, &ret);
//     std::cout << "main thread quit, n =  "<< n 
//     << "main thread get a ret:  "<< (long long)ret <<  std::endl;

//     return 0;
// }







// 1. 多线程创建
// 2. 线程传参和返回值，我们可以传递级别信息，也可以传递其他对象(包括你自己定义的！)
// 3. C++11也带了多线程，和我们今天的是什么关系？？？ TODO下节课
// int main()
// {
//     std::vector<pthread_t> threads;
//     for (int i = 0; i < threadnum; i++)
//     {
//         char threadname[64];
//         snprintf(threadname, 64, "Thread-%d", i + 1);
//         ThreadData *td = new ThreadData(10, 20, threadname);

//         pthread_t tid;
//         pthread_create(&tid, nullptr, handlerTask, td);
//         threads.push_back(tid);
//     }
//     std::vector<Result*> result_set;
//     void *ret = nullptr;
//     for (auto &tid : threads)
//     {
//         pthread_join(tid, &ret);
//         result_set.push_back((Result*)ret);
//     }

//     for(auto & res : result_set)
//     {
//         res->Print();
//         delete res;
//     }
// }

// // 同一个进程内的线程，大部分资源都是共享的. 地址空间是共享的！




// // 线程退出
// // 1. 代码跑完，结果对
// // 2. 代码跑完，结果不对
// // 3. 出异常了 --- 重点 --- 多线程中，任何一个线程出现异常(div 0， 野指针), 都会导致整个进程退出！ ---- 多线程代码往往健壮性不好
// void *threadrun(void *args)
// {
//     std::string threadname = (char*)args;
//     int cnt = 5;
//     while (cnt)
//     {
//         printf("new thread, g_val: %d, &g_val: %p\n", g_val, &g_val);

//         // std::cout << threadname << " is running: " << cnt << ", pid: " << getpid()
//         //     << " mythread id: " << ToHex(pthread_self())
//         //     << "g_val: "<< g_val << " &g_val: " << &g_val << std::endl;
//         g_val++;
//         sleep(1);
//         // int *p = nullptr;
//         // *p = 100; // 故意一个野指针
//         cnt--;
//     }
//     // 1. 线程函数结束
//     // 2. pthread_exit()
//     // pthread_exit((void*)123);
//     // exit(10); // 不能用exit终止线程，因为它是终止进程的.
//     return (void*)123; // warning
// }

